package com.paginasenlanube.service;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.paginasenlanube.dao.GenericDao;
import com.paginasenlanube.model.DataType;
import com.paginasenlanube.pages.ArchivePage;
import com.paginasenlanube.pages.CatalogPage;
import com.paginasenlanube.pages.FormPage;
import com.paginasenlanube.pages.DataTypePage;
import com.paginasenlanube.pages.ImageGalPage;
import com.paginasenlanube.pages.VideoGalPage;
import com.paginasenlanube.model.Archive;
import com.paginasenlanube.model.Image;
import com.paginasenlanube.model.ImageGallery;
import com.paginasenlanube.model.Page;
import com.paginasenlanube.model.Website;
import com.paginasenlanube.utils.Utils;
import com.paginasenlanube.view.Config;

@Service
public class PagesConfigServiceImpl implements PagesConfigService{
	
	
	 @Autowired
	 @Qualifier("hibernateDao")
	 private GenericDao dao;
	  
	 public GenericDao getDao() {
		return dao;
	 }
	 
	 @Resource(name = "myProps")
	 private Properties myProps;
	 
	 @Autowired
	 private Config cfg;
	 
	 @Autowired
	 private Website website;
	 
	@Override
	@Transactional
	public Page updatePageTemplate(String template,String pageId) {
		long id = Long.parseLong(pageId);
		Page p = dao.getObjectById(Page.class,id);
		p.setTemplate(template);
		dao.update(p); 
		if(p.getPageType().equals("dataType")){
			updateZones(p);
			return getDataTypePage(id,p);
		}
		return p;
	}
	
	@Transactional
	public void updateZones(Page page){
		if(deleteDataTypes(page)){
			if(page.getTemplate().equals("1Col1Accordion")){
				DataType n1 = new DataType();
				n1.setPageId(page.getId());
				dao.add(n1);
			}else if(page.getTemplate().equals("2ColAside")){
				DataType n1 = new DataType();
				DataType n2 = new DataType();
				n1.setPageId(page.getId());
				n2.setPageId(page.getId());
				dao.add(n1);
				dao.add(n2);			
			}else if(page.getTemplate().equals("3Col1Text")){
				DataType n1 = new DataType();
				DataType n2 = new DataType();
				DataType n3 = new DataType();
				n1.setPageId(page.getId());
				n2.setPageId(page.getId());
				n3.setPageId(page.getId());
				dao.add(n1);
				dao.add(n2);
				dao.add(n3);
			}
		}
	}
	
	
	@Override
	@Transactional
	public Page getPage(String page) {
		long id = Long.parseLong(page.substring(4));
		Page hp = dao.getObjectById(Page.class,id);
		Page p = new Page(); 
				 
		if(hp.getPageType().equals("dataType")){
			return getDataTypePage(id,hp);
		 }
		if(hp.getPageType().equals("archive")){
			return getArchivePage(id,hp);
		 }
		if(hp.getPageType().equals("catalog")){
			return getCatalogPage(id,hp);
		 }
		if(hp.getPageType().equals("imageGal")){
			return getImageGalPage(id,hp);
		 }
		if(hp.getPageType().equals("videoGal")){
			return getVideoGalPage(id,hp);
		 }
		if(hp.getPageType().equals("formType")){
			return getFormPage(id,hp);
		 }
		
		return p;
	
	}
	
	//////DATATYPE///////////////
	
	@Override
	@Transactional
	public void updateDataTypePage(DataType dt){
		 long id =  dt.getId();
		 DataType dataType = dao.getObjectById(DataType.class, id);
		 String title =  dt.getTitle();
		 String text =  dt.getParagraph();
		 if(!title.isEmpty())dataType.setTitle(title);
		 if(!text.isEmpty())dataType.setParagraph(text);
	 
		dao.update(dataType);
		
	}
	
	
	public boolean deleteDataTypes(Page page){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pageId", page.getId());
		//delete images
		List<DataType> objs = dao.getObjectsByEqCriteria(DataType.class,params,null);
		for(DataType dataType : objs){
			if(dataType.getImage() != null){
				 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+dataType.getImage().getFileName());
				 f_old.delete();
			}
		}
		return dao.deleteObjectsByEqCriteria(DataType.class,params);
	}
	
	@Override
	@Transactional
	public DataTypePage deleteDataType(String pageId,String dataTypeId){
		long dtId = Long.parseLong(dataTypeId);
		 DataType dataType = dao.getObjectById(DataType.class, dtId);
		 if(dataType.getImage() != null){
			 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+dataType.getImage().getFileName());
			 f_old.delete();
		}
		 dao.delete(dataType);
		
		long id = Long.parseLong(pageId);
		Page p = dao.getObjectById(Page.class,id);
		return getDataTypePage(id,p);
	}

	@Override
	@Transactional
	public Page addDataType(String pageId) {
		long id = Long.parseLong(pageId);
		Page p = dao.getObjectById(Page.class,id);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pageId", id);
		Order order = Order.asc("id");
		List<DataType> dataTypes = dao.getObjectsByEqCriteria(DataType.class, params, order);
		if(dataTypes.size()<10){
		DataType n1 = new DataType();
		n1.setPageId(p.getId());
		dao.add(n1);
		}
		return getDataTypePage(id,p);
	}
	
	private DataTypePage getDataTypePage(long id,Page hp){
		DataTypePage dataTypePage = new DataTypePage();
		dataTypePage.setLimit(myProps.getProperty(hp.getPageType()+"."+hp.getTemplate()+"_elements"));
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pageId", id);
		Order order = Order.asc("id");
		List<DataType> dataTypes = dao.getObjectsByEqCriteria(DataType.class, params, order);
		dataTypePage.setDataTypes(dataTypes);
		
		dataTypePage.setId(hp.getId());
		dataTypePage.setTemplate(hp.getTemplate());
		dataTypePage.setPageType(hp.getPageType());
		return dataTypePage;
	}
	
	
//////ARCHIVE///////////////
	
	
	private ArchivePage getArchivePage(long id,Page hp){
		ArchivePage archivePage = new ArchivePage();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pageId", id);
		Order order = Order.asc("position");
		List<Archive> archives = dao.getObjectsByEqCriteria(Archive.class, params, order);
		archivePage.setArchives(archives);
		
		archivePage.setId(hp.getId());
		archivePage.setTemplate(hp.getTemplate());
		archivePage.setPageType(hp.getPageType());
		return archivePage;
	}
	
	@Override
	@Transactional
	public String updateArchivePage(Archive ar){
		 long id =  ar.getId();
		 Archive archive = dao.getObjectById(Archive.class, id);
		 String title =  ar.getTitle();
		 String text =  ar.getText();
		 String tags = ar.getTags();
		 String video_url = ar.getVideo_url();
		 archive.setTitle(title);
		 archive.setText(text);
		 archive.setTags(tags);
		 archive.setVideo_url(video_url);
	 
		dao.update(archive);
		return "{\"update\":\"archive\",\"id\":\""+archive.getId()+"\",\"title\":\""+archive.getTitle()+"\"}";
    	
		
	}
	
	@Override
	@Transactional
	public ArchivePage deleteArchive(String pageId,String archiveId){
		long arId = Long.parseLong(archiveId);
		Archive archive = dao.getObjectById(Archive.class, arId);
		 if(archive.getImage() != null){
			 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+archive.getImage().getFileName());
			 f_old.delete();
		}
		 dao.delete(archive);
		
		long id = Long.parseLong(pageId);
		Page p = dao.getObjectById(Page.class,id);
		return getArchivePage(id,p);
	}

	@Override
	@Transactional
	public void updateArchivePosition(JsonArray json) {
		long id1 = Long.parseLong(json.get(0).getAsJsonObject().get("id1").getAsString().substring(8));
		int pos1 = Integer.parseInt(json.get(0).getAsJsonObject().get("pos1").getAsString());
		long id2 = Long.parseLong(json.get(0).getAsJsonObject().get("id2").getAsString().substring(8));
		int pos2 = Integer.parseInt(json.get(0).getAsJsonObject().get("pos2").getAsString());
		
		Archive archive1 = dao.getObjectById(Archive.class,id1);
		archive1.setPosition(pos1);
		dao.update(archive1);
		
		Archive archive2 = dao.getObjectById(Archive.class,id2);
		archive2.setPosition(pos2);
		dao.update(archive2);
		
	}

	@Override
	@Transactional
	public String getArchive(String archiveId) {
		long arId = Long.parseLong(archiveId);
		Archive archive = dao.getObjectById(Archive.class, arId);
		return "{\"update\":\"data\",\"id\":\""+archive.getId()+"\",\"title\":\""+archive.getTitle()+"\",\"text\":\""+archive.getText()+"\",\"video_url\":\""+archive.getVideo_url()+"\",\"tags\":\""+archive.getTags()+"\",\"src\":\"/userimages/"+website.getId()+"/"+archive.getImage().getFileName()+"\"}";
    	
	}
	
//////CATALOG///////////////
	
	private CatalogPage getCatalogPage(long id,Page hp){
		CatalogPage cp = new CatalogPage();
		cp.setId(hp.getId());
		cp.setPageType(hp.getPageType());
		return cp;
		
	}
	
//////IMAGE GAL///////////////
	
	
	private ImageGalPage getImageGalPage(long id,Page hp){
		ImageGalPage igp = new ImageGalPage();
		igp.setId(hp.getId());
		igp.setPageType(hp.getPageType());
		igp.setTemplate(hp.getTemplate());
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("pageId", id);
		Order order = Order.asc("position");
		List<ImageGallery> galleries = dao.getObjectsByEqCriteria(ImageGallery.class, params, order);
		igp.setImageGalleries(galleries);
		return igp;
		
	}
	
	@Override
	@Transactional
	public String addImageGallery(String pageId, String name, String description) {
		
		long id = Long.parseLong(pageId);
		Page p = dao.getObjectById(Page.class,id);
		ImageGallery gallery = new ImageGallery();
		gallery.setName(name);
		gallery.setDescription(description);
		gallery.setPageId(id);
		dao.add(gallery);
		ImageGalPage igp =  getImageGalPage(id,p);
        List<ImageGallery> gals = igp.getImageGalleries();
   	    Gson gson = new Gson();
		String json = gson.toJson(gals);
	    return json;
	}
	
	@Override
	@Transactional
	public String getImageGallery(String galId) {
		
		long id = Long.parseLong(galId);
		ImageGallery ig = dao.getObjectById(ImageGallery.class,id);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("imageGallery_id", id);
        List<Image> images = dao.getObjectsByEqCriteria(Image.class,params,null);
        Gson gson = new Gson();
		String jsonImages = gson.toJson(images);
		String json = "[{\"name\":\""+ig.getName()+"\",\"id\":\""+ig.getId()+"\",\"description\":\""+ig.getDescription()+"\",\"images\":"+jsonImages+"}]";
	    return json;
	}
	
	
	
//////VIDEO GAL///////////////
	
	private VideoGalPage getVideoGalPage(long id,Page hp){
		VideoGalPage vgp = new VideoGalPage();
		vgp.setId(hp.getId());
		vgp.setPageType(hp.getPageType());
		return vgp;
		
	}
	
//////FORMTYPE///////////////
	
	private FormPage getFormPage(long id,Page hp){
		FormPage cp = new FormPage();
		cp.setId(hp.getId());
		cp.setPageType(hp.getPageType());
		return cp;
		
	}



}
